var util = require('util');
var https = require('https');
var qs = require('querystring');
var url = require('url');
var fs = require('fs');
require('buffer');

var Authenticate = function(req, res, next) {
//	util.puts('Entering Auth.Authenticate');
	if(req.session.userId) { // Load profile from database
		model.User.findOne({ _id : req.session.userId }, function(e, user) {
//			util.puts('Loaded Profile. Next');
			req.user = user;
			res.local('user', user);
			next();
		});
	} else {
		req.user = undefined;
		res.local('user', undefined);
//		util.puts('No Profile. Next.');
		next();
	}
};

var Facebook = function(req, res, next) {
//	util.puts('Entering Auth.Facebook');
	
	var login = true;
	if(typeof(arguments[3]) != 'undefined')
		var login = arguments[3];
	
	if(login && typeof(req.session.userId) != 'undefined') {
//		util.puts('Already logged in. Next');
		next();
		return;
	}
	
	if(req.cookies['fbs_' + facebook.appId]) { // Try to get Facebook profile
//		util.puts('No one is logged in, but there is a Facebook cookie!');
		var fbCookie = qs.parse(req.cookies['fbs_' + facebook.appId]);
		var fbData = '';

		https.request({
			host : 'graph.facebook.com',
			port : 443,
			method : 'GET',
			path : '/me?access_token=' + fbCookie['access_token']
		}, function(fbResponse) {
			fbResponse.setEncoding('utf8');
			fbResponse.on('data', function(chunk) {
				fbData += chunk;
			});
			fbResponse.on('end', function() {
				var fbUser = JSON.parse(fbData);
				
//				util.puts('fbId: ' + fbUser.id);
				
				if(typeof(fbUser.id) != 'undefined') {
					model.User.findOne({ fbId : fbUser.id }, function(e, user) {
						if(user) { // Load profile from database, set session userId
							if(login) {
//								util.puts('We already know this guy. Logging him in.');
								req.user = user;
								res.local('user', user);
								req.session.userId = user._id;
								next();
							} else {
								next(user);
							}
						} else { // Add a new user to the database, set session userId
//							util.puts('New guy. Add him to the database, logging him in.');
							var newUser = new model.User();
							newUser.firstName = fbUser.first_name;
							newUser.lastName = fbUser.last_name;
							newUser.fbId = fbUser.id;
							newUser.fbUser = fbUser.username || undefined;
							newUser.fbProfile = fbUser.link;
							newUser.email = fbUser.email;
							newUser.save(function(e) {
//								util.puts('Saving User.');
								if(e) {
//									util.puts('Oh No! An error: ' + e.message);
									res.render('error.jade', {
										title : 'User Error',
										user : undefined,
										error : e,
										pretty : true
									});
								} else if(login) {
									req.session.userId = newUser._id;
									req.user = newUser;
									res.local('user',newUser);
//									util.puts('Sending Welcome message. UID: ' + req.session.userId);
									res.redirect('/');
								} else {
									next(newUser);
								}
								
//								util.puts('Downloading Profile Pic');
								// Download profile picture asynchronously
								httpsFetch({
									host : 'graph.facebook.com',
									port : 443,
									method : 'GET',
									path : '/me/picture?type=large&access_token=' + fbCookie['access_token']
								}, '/home/htdocs/rush/static/profile/' + newUser._id + '.jpg');
							});
						}
					});
				} else if(typeof(fbUser.error) != 'undefined') {
//					util.puts('Got an error from Facebook...');
					res.render('error.jade', {
						title : 'Login Error',
						user : undefined,
						error : fbUser.error.message,
						pretty : true
					});
				} else {
//					util.puts('Shit. I\'ve got nothing.');
					res.render('error.jade', {
						title : 'Login Error',
						user : undefined,
						error : 'Oopse. The tubes are clogged',
						pretty : true
					});
				}			
			});
		}).end();
	} else { // We got nothing.
//		util.puts(':( No user information...');
		req.user = undefined;
		res.local('user', undefined);
		next();
	}
};

function httpsFetch(options, path) {
	var request = https.request(options);
	
	request.on('response', function(response) {
		if(response.statusCode == 302 || response.statusCode == 303) {
//			util.puts('Redirecting to ' + response.headers.location);
			var location = url.parse(response.headers.location);
			httpsFetch({
				host : location.hostname,
				port : 443,
				method : 'GET',
				path : location.pathname + location.search
			}, path);
		} else if(response.statusCode == 200) {
			var file = fs.createWriteStream(path);
			
			response.on('data', function(chunk) {
				file.write(chunk);
			});
			
			response.on('end', function() {
				file.end();
			});
		}
	});
	
	request.end();
}

module.exports.facebook = Facebook;
module.exports.authenticate = Authenticate;
